package com.cmc.cloud.cmclink.doc.util;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.cmc.cloud.cmclink.doc.api.document.emums.TransmodeEnum;
import com.cmc.cloud.cmclink.doc.entity.BlnoVslvoyDO;
import com.cmc.cloud.cmclink.doc.rpcservice.VoyScheduleService;
import com.cmc.cloud.cmclink.doc.vo.blnovslvoyvo.BlnoVslvoyUpdateReqVO;
import com.cmc.cloud.cmclink.doc.vo.specialcargoapplyvo.ApplyAndVoyageInfoVO;
import com.cmc.cloud.cmclink.doc.vo.specialcargoapplyvo.SpecialCargoVoyageUpdateReqVO;
import com.cmc.cloud.cmclink.svl.api.base.enums.SystemEnums;
import com.cmc.cloud.cmclink.svl.api.base.req.VesselVoyReqDTO;
import com.cmc.cloud.cmclink.svl.api.base.resp.VesselVoyRespDTO;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 船名航次工具类
 *
 * @author dev89
 * @date 2025/09/02 09:39
 **/
@Component
@Slf4j
public class VslvoyUtil {

    @Resource
    private VoyScheduleService voyScheduleService;

    /**
     * 获取第一条航线laneCode
     *
     * @param vslvoyList 航次列表
     * @return 第一条航线laneCode
     */
    public static String getFirstLaneCode(List<BlnoVslvoyDO> vslvoyList) {
        BlnoVslvoyDO blnoVslvoyDO = getFirstVslvoy(vslvoyList);
        if (blnoVslvoyDO == null) {
            return null;
        }
        return blnoVslvoyDO.getLaneCodeEx();
    }

    /**
     * 获取第一条船名航次
     *
     * @param vslvoyList 航次列表
     * @return 第一条船名航次
     */
    public static BlnoVslvoyDO getFirstVslvoy(List<BlnoVslvoyDO> vslvoyList) {
        return getFirstVslvoy(vslvoyList, TransmodeEnum.LINER.getValue());
    }

    /**
     * 获取第一条非Liner船名航次
     *
     * @param vslvoyList 航次列表
     * @return 第一条船名航次
     */
    public static BlnoVslvoyDO getFirstNoLinerVslvoy(List<BlnoVslvoyDO> vslvoyList) {
        if (CollectionUtils.isEmpty(vslvoyList)) {
            return null;
        }
        Optional<BlnoVslvoyDO> blnoOptinal =
                vslvoyList.stream().filter(vslvoy -> !vslvoy.getTransmode().equals(TransmodeEnum.LINER.getValue()))
                        .min(Comparator.comparingInt(BlnoVslvoyDO::getRouteNo));
        return blnoOptinal.orElse(null);
    }

    /**
     * 获取最后一条非Liner船名航次
     *
     * @param vslvoyList 航次列表
     * @return 第一条船名航次
     */
    public static BlnoVslvoyDO getLastNoLinerVslvoy(List<BlnoVslvoyDO> vslvoyList) {
        if (CollectionUtils.isEmpty(vslvoyList)) {
            return null;
        }
        Optional<BlnoVslvoyDO> blnoOptinal =
                vslvoyList.stream().filter(vslvoy -> !vslvoy.getTransmode().equals(TransmodeEnum.LINER.getValue()))
                        .max(Comparator.comparingInt(BlnoVslvoyDO::getRouteNo));
        return blnoOptinal.orElse(null);
    }

    /**
     * 获取第一条船名航次
     *
     * @param vslvoyList 航次列表
     * @param transmode  运输模式
     * @return 第一条船名航次
     */
    public static BlnoVslvoyDO getFirstVslvoy(List<BlnoVslvoyDO> vslvoyList, String transmode) {
        if (CollectionUtils.isEmpty(vslvoyList)) {
            return null;
        }
        Optional<BlnoVslvoyDO> blnoOptinal =
                vslvoyList.stream().filter(vslvoy -> vslvoy.getTransmode().equals(transmode))
                        .min(Comparator.comparingInt(BlnoVslvoyDO::getRouteNo));
        return blnoOptinal.orElse(null);
    }

    /**
     * 获取最后一条船名航次
     *
     * @param vslvoyList 航次列表
     * @return 最后一条船名航次
     */
    public static BlnoVslvoyDO getLastVslvoy(List<BlnoVslvoyDO> vslvoyList) {
        return getLastVslvoy(vslvoyList, TransmodeEnum.LINER.getValue());
    }

    /**
     * 获取最后一条船名航次
     *
     * @param vslvoyList 航次列表
     * @param transmode  运输模式
     * @return 最后一条船名航次
     */
    public static BlnoVslvoyDO getLastVslvoy(List<BlnoVslvoyDO> vslvoyList, String transmode) {
        if (CollectionUtils.isEmpty(vslvoyList)) {
            return null;
        }
        Optional<BlnoVslvoyDO> blnoOptinal =
                vslvoyList.stream().filter(vslvoy -> vslvoy.getTransmode().equals(transmode))
                        .max(Comparator.comparingInt(BlnoVslvoyDO::getRouteNo));
        return blnoOptinal.orElse(null);
    }

    /**
     * 获取最后一条船名航次
     *
     * @param vslvoyList 航次列表
     * @return 最后一条船名航次
     */
    public static BlnoVslvoyDO getLastVslvoyAllTransMode(List<BlnoVslvoyDO> vslvoyList) {
        if (CollectionUtils.isEmpty(vslvoyList)) {
            return new BlnoVslvoyDO();
        }
        Optional<BlnoVslvoyDO> blnoOptinal = vslvoyList.stream().max(Comparator.comparingInt(BlnoVslvoyDO::getRouteNo));
        return blnoOptinal.orElse(new BlnoVslvoyDO());
    }

    /**
     * 获取第一条船名航次
     *
     * @param vslvoyList 航次列表
     * @return 最后一条船名航次
     */
    public static BlnoVslvoyDO getFirstVslvoyAllTransMode(List<BlnoVslvoyDO> vslvoyList) {
        if (CollectionUtils.isEmpty(vslvoyList)) {
            return new BlnoVslvoyDO();
        }
        Optional<BlnoVslvoyDO> blnoOptinal = vslvoyList.stream().min(Comparator.comparingInt(BlnoVslvoyDO::getRouteNo));
        return blnoOptinal.orElse(new BlnoVslvoyDO());
    }

    /**
     * 获取进口计费港口
     *
     * @param vslvoyList 航次列表
     * @return 进口计费港口
     */
    public static String getLastPort(List<BlnoVslvoyDO> vslvoyList) {
        BlnoVslvoyDO blnoVslvoyDO = getLastVslvoy(vslvoyList);
        if (blnoVslvoyDO == null) {
            return null;
        }
        return blnoVslvoyDO.getPodCode();
    }

    /**
     * 获取出口计费港口
     *
     * @param vslvoyList 航次列表
     * @return 出口计费港口
     */
    public static String getFirstPort(List<BlnoVslvoyDO> vslvoyList) {
        BlnoVslvoyDO blnoVslvoyDO = getFirstVslvoy(vslvoyList);
        if (blnoVslvoyDO == null) {
            return null;
        }
        return blnoVslvoyDO.getPolCode();
    }

    public void setEtaAndEtd(List<BlnoVslvoyUpdateReqVO> vslvoyList) {
        if (CollectionUtil.isNotEmpty(vslvoyList)) {
            vslvoyList.forEach(e -> {
                if(TransmodeEnum.LINER.getValue().equals(e.getTransmode())){
                    Map<String, VesselVoyRespDTO> terminalMap =
                            getVoyTimeMap(e.getPolCode(), e.getVoyageEx(), e.getVesselCode());
                    if (terminalMap != null) {
                        VesselVoyRespDTO vesselVoyRespDTO =
                                terminalMap.get(e.getPolCode() + e.getVoyageEx() + e.getVesselCode());
                        if (vesselVoyRespDTO != null) {
                            e.setPodEta(StringUtils.isNotEmpty(vesselVoyRespDTO.getEta()) ? vesselVoyRespDTO.getEta()
                                    : vesselVoyRespDTO.getPta());
                            e.setPolEtd(StringUtils.isNotEmpty(vesselVoyRespDTO.getEtd()) ? vesselVoyRespDTO.getEtd()
                                    : vesselVoyRespDTO.getPtd());
                        }
                    }
                }
            });
        }

    }

    public String getEtd(String polCode, String voyage, String vessel) {
        String polEtd = StringUtils.EMPTY;
        Map<String, VesselVoyRespDTO> terminalMap = getVoyTimeMap(polCode, voyage, vessel);
        if (terminalMap != null) {
            VesselVoyRespDTO vesselVoyResp = terminalMap.get(polCode + voyage + vessel);
            if (null != vesselVoyResp) {
                polEtd =
                        StringUtils.isNotEmpty(vesselVoyResp.getEtd()) ? vesselVoyResp.getEtd() : vesselVoyResp.getPtd();
            }
        }
        return polEtd;
    }

    public VesselVoyRespDTO getVesselVoyRespDTO(String polCode, String voyage, String vessel) {
        Map<String, VesselVoyRespDTO> terminalMap = getVoyTimeMap(polCode, voyage, vessel);
        if (terminalMap != null) {
            return terminalMap.get(polCode + voyage + vessel);
        }
        return null;
    }

    public void setEtd(List<SpecialCargoVoyageUpdateReqVO> voyages) {
        if (CollectionUtil.isNotEmpty(voyages)) {
            voyages.forEach(e -> {
                Map<String, VesselVoyRespDTO> terminalMap =
                        getVoyTimeMap(e.getPolCode(), e.getVoyageEx(), e.getVesselCode());
                if (terminalMap != null) {
                    VesselVoyRespDTO vesselVoyRespDTO =
                            terminalMap.get(e.getPolCode() + e.getVoyageEx() + e.getVesselCode());
                    if (vesselVoyRespDTO != null) {
                        e.setPolEtd(StringUtils.isNotEmpty(vesselVoyRespDTO.getEtd()) ? vesselVoyRespDTO.getEtd()
                                : vesselVoyRespDTO.getPtd());
                    }
                }
            });
        }
    }

    public void setEtdPage(List<ApplyAndVoyageInfoVO> records) {
        if (CollectionUtil.isNotEmpty(records)) {
            records.forEach(e -> {
                Map<String, VesselVoyRespDTO> terminalMap =
                        getVoyTimeMap(e.getPolCode(), e.getVoyageEx(), e.getVesselCode());
                if (terminalMap != null) {
                    VesselVoyRespDTO vesselVoyRespDTO =
                            terminalMap.get(e.getPolCode() + e.getVoyageEx() + e.getVesselCode());
                    if (vesselVoyRespDTO != null) {
                        e.setPolEtd(StringUtils.isNotEmpty(vesselVoyRespDTO.getEtd()) ? vesselVoyRespDTO.getEtd()
                                : vesselVoyRespDTO.getPtd());
                        e.setPolEtd(StringUtils.isNotEmpty(vesselVoyRespDTO.getEtd()) ? vesselVoyRespDTO.getEtd()
                                : vesselVoyRespDTO.getPtd());
                    }
                }
            });
        }
    }

    private Map<String, VesselVoyRespDTO> getVoyTimeMap(String polCode, String voyage, String vessel) {
        Map<String, VesselVoyRespDTO> result = new HashMap<>(16);
        try {
            VesselVoyReqDTO vesselVoyReqDTO = new VesselVoyReqDTO();
            vesselVoyReqDTO.setPortCode(polCode);
            vesselVoyReqDTO.setVoy(voyage);
            vesselVoyReqDTO.setVesselCodeList(Collections.singletonList(vessel));
            vesselVoyReqDTO.setSystemNumber(SystemEnums.DOC.getSystemNumber());
            List<VesselVoyRespDTO> listVesselVoy = voyScheduleService.listVesselVoy(vesselVoyReqDTO);
            log.info("voyScheduleService.listVesselVoy vesselVoyReqDTO :{} listVesselVoy:{}", vesselVoyReqDTO, listVesselVoy);
            if (CollectionUtils.isEmpty(listVesselVoy)) {
                return result;
            }
            return listVesselVoy.stream()
                    .collect(Collectors.toMap(item -> item.getPortCode() + item.getExVoy() + item.getVesselCode(),
                            item -> item, (first, second) -> first));
        } catch (Exception e) {
            // 异常直接返回
            return result;
        }
    }
    public String getVoyPortTerminal(String polCode, String voyage, String vessel) {
        try {
            VesselVoyReqDTO vesselVoyReqDTO = new VesselVoyReqDTO();
            vesselVoyReqDTO.setPortCode(polCode);
            vesselVoyReqDTO.setVoy(voyage);
            vesselVoyReqDTO.setVesselCodeList(Arrays.asList(vessel));
            vesselVoyReqDTO.setSystemNumber(SystemEnums.DOC.getSystemNumber());
            List<VesselVoyRespDTO> listVesselVoy = voyScheduleService.listVesselVoy(vesselVoyReqDTO);
            if (CollectionUtils.isEmpty(listVesselVoy)) {
                return null;
            }
            return listVesselVoy.stream()
                    .filter(e -> StringUtils.isNotEmpty(e.getPortCode()) && StringUtils.isNotEmpty(e.getTerminalCode()))
                    .map(VesselVoyRespDTO::getTerminalCode).findAny().orElse(null);
        } catch (Exception e) {
            // 异常直接返回
            return null;
        }
    }
    public VesselVoyRespDTO getVoyPtaCtm(String port, String voyage, String vessel) {
        try {
            VesselVoyReqDTO vesselVoyReqDTO = new VesselVoyReqDTO();
            vesselVoyReqDTO.setPortCode(port);
            vesselVoyReqDTO.setVoy(voyage);
            vesselVoyReqDTO.setVesselCodeList(Collections.singletonList(vessel));
            vesselVoyReqDTO.setSystemNumber(SystemEnums.DOC.getSystemNumber());
            List<VesselVoyRespDTO> listVesselVoy = voyScheduleService.listVesselVoy(vesselVoyReqDTO);
            log.info("voyScheduleService_listVesselVoy_getVoyPtaCtm_info vesselVoyReqDTO :{} listVesselVoy:{}", vesselVoyReqDTO, listVesselVoy);
            if (CollectionUtils.isEmpty(listVesselVoy)) {
                return null;
            }
            return listVesselVoy.get(0);
        } catch (Exception e) {
            log.error("voyScheduleService_listVesselVoy_getVoyPtaCtm_error:{}",e.getMessage());
        }
        return null;
    }
}
